/**
 * 
 */
package org.crystal.jqweb.json;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.crystal.jqweb.db.Column;
import org.crystal.jqweb.util.BeanUtils;

/**
 * @author Crystal
 *
 */
public class JsonSerialize {
	private final Log log = LogFactory.getLog(getClass());
	/**
	 * 
	 */
	public JsonSerialize() {
		// TODO Auto-generated constructor stub
	}
	public <T> String toJsonString(T bean){
		log.debug("toJsonString json bean Class is:"+bean.getClass());
		
		if(bean.getClass().isArray()){
			log.debug("toJsonString json bean Class is:"+bean.getClass().isArray());
			//return arrayToJsonString(bean);
		}
		StringBuffer sbJson=new StringBuffer("{");
		Field [] fields = bean.getClass().getDeclaredFields();
		 for (Field field : fields) {
          	if (field.isAnnotationPresent(Json.class)) {
          		if(sbJson.toString().equals("{")){
          			sbJson.append(getFieldJsonString(bean,field));
          		}else{
          			sbJson.append(","+getFieldJsonString(bean,field));
          		}
          	}
		 }
		 sbJson.append("}");
		 log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	
	public <T> String toJsonString(T []arraybean){
		log.debug("toJsonString json Array length is:"+arraybean.length);
		StringBuffer sbJson=new StringBuffer("[");
		for(int i=0;i<arraybean.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append(toJsonString(arraybean[i]));
			}else{
				sbJson.append(","+toJsonString(arraybean[i]));
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(int []arrayInt){
		log.debug("toJsonString json int Array length is:"+arrayInt.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayInt.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayInt[i]+"\"");
			}else{
				sbJson.append(",\""+arrayInt[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(float []arrayFloat){
		log.debug("toJsonString json float Array length is:"+arrayFloat.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayFloat.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayFloat[i]+"\"");
			}else{
				sbJson.append(",\""+arrayFloat[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(double []arrayDouble){
		log.debug("toJsonString json double Array length is:"+arrayDouble.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayDouble.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayDouble[i]+"\"");
			}else{
				sbJson.append(",\""+arrayDouble[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(char []arrayChar){
		log.debug("toJsonString json char Array length is:"+arrayChar.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayChar.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayChar[i]+"\"");
			}else{
				sbJson.append(",\""+arrayChar[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(boolean []arrayBoolean){
		log.debug("toJsonString json boolean Array length is:"+arrayBoolean.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayBoolean.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayBoolean[i]+"\"");
			}else{
				sbJson.append(",\""+arrayBoolean[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(Boolean []arrayBoolean){
		log.debug("toJsonString json Boolean Array length is:"+arrayBoolean.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayBoolean.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayBoolean[i]+"\"");
			}else{
				sbJson.append(",\""+arrayBoolean[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(short []arrayshort){
		log.debug("toJsonString json short Array length is:"+arrayshort.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayshort.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayshort[i]+"\"");
			}else{
				sbJson.append(",\""+arrayshort[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(long []arraylong){
		log.debug("toJsonString json long Array length is:"+arraylong.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arraylong.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arraylong[i]+"\"");
			}else{
				sbJson.append(",\""+arraylong[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(byte []arraybyte){
		log.debug("toJsonString json byte Array length is:"+arraybyte.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arraybyte.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arraybyte[i]+"\"");
			}else{
				sbJson.append(",\""+arraybyte[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(String []arrayString){
		log.debug("toJsonString json String Array length is:"+arrayString.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayString.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayString[i]+"\"");
			}else{
				sbJson.append(",\""+arrayString[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public  String toJsonString(Date []arrayDate){
		log.debug("toJsonString json Date Array length is:"+arrayDate.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arrayDate.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arrayDate[i]+"\"");
			}else{
				sbJson.append(",\""+arrayDate[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	//BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, and Short.
	public  String toJsonString(Number []arraybyte){
		log.debug("toJsonString json Number Array length is:"+arraybyte.length);
		StringBuffer sbJson=new StringBuffer("[");

		for(int i=0;i<arraybyte.length;i++){
			if(sbJson.toString().equals("[")){
				sbJson.append("\""+arraybyte[i]+"\"");
			}else{
				sbJson.append(",\""+arraybyte[i]+"\"");
			}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}

	public <T> String toJsonString(List <T> list){
		log.debug("toJsonString json List  Size is:"+list.size());
		StringBuffer sbJson=new StringBuffer("[");
		Iterator<T> itList=list.iterator();
		while(itList.hasNext()){
			if(sbJson.toString().equals("[")){
      			sbJson.append(getValueJsonString(itList.next()));
      		}else{
      			sbJson.append(","+getValueJsonString(itList.next()));
      		}
		}	
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	
	public <T> String toJsonString(Set <T> set){
		log.debug("toJsonString json Set  Size is:"+set.size());
		StringBuffer sbJson=new StringBuffer("[");
		Iterator<T> itSet=set.iterator();
		while(itSet.hasNext()){
			if(sbJson.toString().equals("[")){
      			sbJson.append(getValueJsonString(itSet.next()));
      		}else{
      			sbJson.append(","+getValueJsonString(itSet.next()));
      		}
		}
		 sbJson.append("]");
		 log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public <T> String toJsonString(Collection <T> col){
		log.debug("toJsonString json Collection  Size is:"+col.size());
		StringBuffer sbJson=new StringBuffer("[");
		Iterator<T> itCol=col.iterator();
		while(itCol.hasNext()){
			if(sbJson.toString().equals("[")){
      			sbJson.append(getValueJsonString(itCol.next()));
      		}else{
      			sbJson.append(","+getValueJsonString(itCol.next()));
      		}
		}
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	public <T> String toJsonString(Map <T,T> map){
		log.debug("toJsonString json Map  Size is:"+map.size());
		StringBuffer sbJson=new StringBuffer("[");
		Iterator  itMap   =   map.entrySet().iterator();    
		while(itMap.hasNext()){ 
			Map.Entry entry=(Map.Entry)itMap.next();    
		  	Object key=entry.getKey();    
		  	log.debug("toJsonString json Map key is:"+key.toString());
		  	Object value=entry.getValue();  
		  	if(sbJson.toString().equals("[")){
		  		sbJson.append("\""+key.toString()+"\":");
      			sbJson.append(getValueJsonString(value));
      		}else{
      			sbJson.append(",\""+key.toString()+"\":");
      			sbJson.append(""+getValueJsonString(value));
      		}
		}   	
		sbJson.append("]");
		log.info("toJsonString() sbJson:"+sbJson.toString());
		return sbJson.toString();
	}
	
	private <T> String getFieldJsonString(T bean,Field field){
		String jsonString="";
		String fieldValue="";
		Json jsonAnnotation = field.getAnnotation(Json.class);
		if(jsonAnnotation.name()!=null&&!jsonAnnotation.name().equals("")){
			jsonString="\""+jsonAnnotation.name()+"\":";
		}else{
			jsonString="\""+field.getName()+"\":";
		}
		
		String fieldType=field.getType().getName();
		String fillValue=null;
		try {
			if(BeanUtils.get(bean, field.getName())!=null){
				fillValue = BeanUtils.get(bean, field.getName()).toString();
			}else{
				if(jsonAnnotation.value()!=null&&!jsonAnnotation.value().equals("")){
					return jsonString+="\""+jsonAnnotation.value()+"\"";
				}else{
					return jsonString+"\"null\"";
				}	
			}
		} catch (IllegalArgumentException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if(fieldType.equals("java.lang.String")){
			fieldValue= "\""+String.valueOf(fillValue)+"\"";
        }else if(fieldType.equals("int")){
        	fieldValue= "\""+Integer.parseInt(fillValue+"\"");
        }else if(fieldType.equals("long")){
        	fieldValue= "\""+Long.parseLong(fillValue)+"\"";
        }else if(fieldType.equals("java.lang.Long")){
        	fieldValue= "\""+Long.parseLong(fillValue)+"\"";
        }else if(fieldType.equals("double")){
        	fieldValue= "\""+Double.valueOf(fillValue)+"\"";
        }else if(fieldType.equals("float")){
        	fieldValue= "\""+Float.parseFloat(fillValue)+"\"";
        }else if(fieldType.equals("java.util.Date")){ 
        	fieldValue ="\""+(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(BeanUtils.get(bean, field.getName())).toString()+"\"";
        }else if(fieldType.equals("char")){
        	fieldValue= "\""+Character.valueOf(fillValue.charAt(0))+"\"";
        }else if(fieldType.equals("boolean")){
        	fieldValue= "\""+ Boolean.parseBoolean(fillValue)+"\"";
        }else if(fieldType.equals("short")){
        	fieldValue= "\""+Short.parseShort(fillValue)+"\"";
        }else if(fieldType.equals("byte")){
        	fieldValue= "\""+Byte.parseByte(fillValue)+"\"";
        }else if(fieldType.equals("java.lang.Object")){
        	if(BeanUtils.get(bean, field.getName())!=null){
        		fieldValue=toJsonString(BeanUtils.get(bean, field.getName()));
        	}
			log.debug("getFieldJsonString() Class  is Object  invoke toJsonString()");
        }else if((BeanUtils.get(bean, field.getName()).getClass().getSuperclass().getName().toString()).equals("java.lang.Object")){
        	if(BeanUtils.get(bean, field.getName())!=null){
        		fieldValue=toJsonString(BeanUtils.get(bean, field.getName()));
        	}
			log.debug("getFieldJsonString() Superclass  is Object  invoke toJsonString()");
        }else {
        	if(BeanUtils.get(bean, field.getName())!=null){
        		fieldValue=toJsonString(BeanUtils.get(bean, field.getName()));
        	}
			log.debug("getFieldJsonString()  class  is "+BeanUtils.get(bean, field.getName()).getClass().getName().toString()+"  invoke toJsonString()");
        }
		jsonString+=""+fieldValue+"";
		
		log.debug("getFieldJsonString() jsonString:"+jsonString);
		log.debug("getFieldJsonString() fieldName:"+field.getName()+",fieldType:"+fieldType+",Value:"+fillValue+",fieldValue:"+fieldValue);
		return jsonString;
	}
	private <T> String getValueJsonString(T value){
		String jsonString="";
		String fieldValue="";
		
		String fieldType=value.getClass().getName().toString();
		String fillValue=value.toString();
	
		if(fieldType.equals("java.lang.String")){
			fieldValue= "\""+String.valueOf(fillValue)+"\"";
        }else if(fieldType.equals("int")){
        	fieldValue= "\""+Integer.parseInt(fillValue)+"\"";
        }else if(fieldType.equals("long")){
        	fieldValue= "\""+Long.parseLong(fillValue)+"\"";
        }else if(fieldType.equals("java.lang.Long")){
        	fieldValue= "\""+Long.parseLong(fillValue)+"\"";
        }else if(fieldType.equals("double")){
        	fieldValue= "\""+Double.valueOf(fillValue)+"\"";
        }else if(fieldType.equals("float")){
        	fieldValue= ""+Float.parseFloat(fillValue);
        }else if(fieldType.equals("java.util.Date")){ 
        	fieldValue ="\""+(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(value).toString()+"\"";
        }else if(fieldType.equals("char")){
        	fieldValue= "\""+Character.valueOf(fillValue.charAt(0))+"\"";
        }else if(fieldType.equals("boolean")){
        	fieldValue= "\""+ Boolean.parseBoolean(fillValue)+"\"";
        }else if(fieldType.equals("short")){
        	fieldValue= "\""+Short.parseShort(fillValue)+"\"";
        }else if(fieldType.equals("byte")){
        	fieldValue= "\""+Byte.parseByte(fillValue)+"\"";
        }else if(fieldType.equals("java.lang.Object")){
        	if(value!=null){
        		fieldValue=toJsonString(value);
        	}
			log.debug("getObjectJsonString() Class  is Object  invoke toJsonString()");
        }else if((value.getClass().getSuperclass().getName().toString()).equals("java.lang.Object")){
        	if(value!=null){
        		fieldValue=toJsonString(value);
        	}
			log.debug("getObjectJsonString() Superclass  is Object  invoke toJsonString()");
        }else {
        	if(value!=null){
        		fieldValue=toJsonString(value);
        	}
			log.debug("getObjectJsonString()  class  is "+value.getClass().getName().toString()+"  invoke toJsonString()");
        }
		
		jsonString+=""+fieldValue+"";
		
		log.debug("getObjectJsonString() jsonString:"+jsonString);
		log.debug("getObjectJsonString() Object Type:"+fieldType+",Value:"+fillValue+",fieldValue:"+fieldValue);
		return jsonString;
	}
}
